package routines

import (
	"fmt"
	"math/rand"
	"sync/atomic"
	"time"
)

type readOp struct {
	key  int
	resp chan int
}

type writeOp struct {
	key  int
	val  int
	resp chan bool
}

func DemoStatefulGoroutines() {

	var ops int64

	//构建两个通道，分别代表read 和 write。
	reads := make(chan *readOp)
	writes := make(chan *writeOp)

	for r := 0; r < 100; r++ {

		go func() {
			read := &readOp{
				key:  rand.Intn(5),
				resp: make(chan int)}
			reads <- read
			fmt.Println("read:", <-read.resp)
			atomic.AddInt64(&ops, 1)
		}()
	}

	for w := 0; w < 10; w++ {
		go func() {
			write := &writeOp{
				key:  rand.Intn(5),
				val:  rand.Intn(100),
				resp: make(chan bool)}
			writes <- write
			fmt.Println("write:", <-write.resp)
			atomic.AddInt64(&ops, 1)
		}()
	}

	go func() {
		var state = make(map[int]int)
		for {
			select {
			case read := <-reads:
				read.resp <- state[read.key]
			case write := <-writes:
				state[write.key] = write.val
				write.resp <- true

			}
		}
	}()
	time.Sleep(time.Second)

	opsFinal := atomic.LoadInt64(&ops)
	fmt.Println("ops:", opsFinal)
}
